#include <bits/stdc++.h>
using namespace std;

typedef long long ll;

const int N=1e5+5, M=1e6+5;

int n,m,len,tot,tree[M];
int pos[N];
ll maxV;

struct vehicle{
    ll d,v,a;
}raw[N];

struct seg{
    int L,R;
}car[N];

bool cmp(seg x,seg y){
    return x.R<y.R;
}

inline int lowbit(int x){
    return x&(-x);
}

void update(int x,int delta){
    for(;x<=1e6;x+=lowbit(x))
        tree[x]+=delta;
}

int query(int x){
    int ans=0;
    for(;x>=1;x-=lowbit(x))
        ans+=tree[x];
    return ans;
}

int query(int l,int r){
    return query(r)-query(l-1);
}

// v0 -> v1 s=(v1^2-v0^2)/2a

void solve(){
    memset(tree,0,sizeof(tree));
    scanf("%d%d%d%lld",&n,&m,&len,&maxV);
    tot=0;
    for(int i=1;i<=n;++i)
        scanf("%lld%lld%lld",&raw[i].d,&raw[i].v,&raw[i].a);
    for(int i=1;i<=m;++i) scanf("%d",&pos[i]);
    sort(pos+1,pos+m+1);
    for(int i=1;i<=n;++i){
        ll d,v,a;
        d=raw[i].d, v=raw[i].v, a=raw[i].a;
        bool over=false;
        int L,R;
        if(a==0){
            if(v>maxV){
                over=true;
                L=d, R=len;
            }
        }
        else if(a<0){
            if(v>maxV){
                over=true;
                ll p=maxV*maxV-v*v, q=2*a;
                ll dist=p/q;
                if(p%q==0) dist--;

                L=d, R=d+dist;
            }
        }
        else{
            if(v>maxV){
                over=true;
                L=d, R=len;
            }
            else{
                ll p=maxV*maxV-v*v, q=2*a;
                ll dist=p/q;
                if(p%q==0) dist++;
                if(d+dist<=len){
                    over=true;
                    L=d+dist, R=len;
                }
            }
        }
        if(over){
            //cout<<L<<' '<<R<<endl;
            int ct=lower_bound(pos+1,pos+m+1,L)-pos;
            if(ct<=m&&pos[ct]<=R){
                //cout<<i<<endl;
                car[++tot].L=L;
                car[tot].R=R;
            }
        }
    }
    printf("%d ",tot);

    int selected=0;
    sort(car+1,car+tot+1,cmp);
    for(int i=1;i<=tot;++i){
        if(query(car[i].L,car[i].R)==0){
            int x=upper_bound(pos+1,pos+m+1,car[i].R)-pos-1;
            update(pos[x],1);
            selected++;
        }
    }
    printf("%d\n",m-selected);
}

int main(){
    freopen("detect.in","r",stdin);
    freopen("detect.out","w",stdout);
    int T;
    scanf("%d",&T);
    while(T--) solve();
    return 0;
}
